package com.example.autooperation.executor;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.autooperation.entity.Step;
import com.example.autooperation.entity.StepType;
import com.example.autooperation.entity.Task;
import com.example.autooperation.service.LogService;
import com.example.autooperation.service.StepService;
import com.example.autooperation.service.TaskService;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Component
public class MyTaskExecutor {

    @Autowired
    private TaskService taskService;

    @Autowired
    private StepService stepService;

    @Autowired
    private LogService logService;

    private final Map<Integer, TaskExecution> taskExecutionMap = new ConcurrentHashMap<>();
    private final ExecutorService executorService = Executors.newCachedThreadPool();

    private static class TaskExecution {
        private volatile boolean paused = false;
        private volatile boolean stopped = false;

        public synchronized void pause() {
            this.paused = true;
        }

        public synchronized void resume() {
            this.paused = false;
            notifyAll();
        }

        public synchronized void stop() {
            this.stopped = true;
            notifyAll();
        }

        public synchronized boolean isPaused() {
            return paused;
        }

        public synchronized boolean isStopped() {
            return stopped;
        }

        public synchronized void checkPause() throws InterruptedException {
            while (paused) {
                wait();
            }
        }
    }

//    public void executeTask(int taskId) {
//        TaskExecution taskExecution = new TaskExecution();
//        taskExecutionMap.put(taskId, taskExecution);
//
//        executorService.submit(() -> {
//            System.out.println("进入submit");
//            // 初始化 WebDriver
//            System.setProperty("webdriver.chrome.driver", "/Users/wkt/code/cursor/autoExecution/backend/src/main/resources/chromedriver");
//            ChromeOptions options = new ChromeOptions();
//            System.out.println("new ChromeOptions()");
//            options.addArguments("--remote-allow-origins=*");
//            WebDriver driver = new ChromeDriver(options);
//            System.out.println("初始化WebDriver");
//            Task task = null;
//            try {
//                System.out.println("进入try");
//                task = taskService.getById(taskId);
//                if (task == null) {
//                    throw new RuntimeException("Task not found: " + taskId);
//                }
//
//                // 更新任务状态为执行中
//                task.setStatus(1);
//                taskService.updateById(task);
//
//                List<Step> steps = stepService.getStepsByTaskId(taskId);
//                int currentStepIndex = 0;
//
//                for (Step step : steps) {
//                    taskExecution.checkPause();
//                    if (taskExecution.isStopped()) {
//                        break;
//                    }
//
//                    currentStepIndex++;
//                    task.setCurrentStep(currentStepIndex);
//                    taskService.updateById(task);
//
//                    logService.createLog(taskId, "开始执行步骤 " + currentStepIndex, LocalDateTime.now());
//
//                    StepType stepType = StepType.fromValue(step.getType());
//                    switch (stepType) {
//                        case CLICK:
//                            WebElement element = findElement(driver, step.getTarget());
//                            element.click();
//                            break;
//                        case INPUT:
//                            WebElement inputElement = findElement(driver, step.getTarget());
//                            inputElement.sendKeys(step.getInputContent());
//                            break;
//                        case EXECUTE_CODE:
//                            ((JavascriptExecutor) driver).executeScript(step.getCode());
//                            break;
//                        case OPEN_URL:
//                            driver.get(step.getTarget());
//                            break;
//                        case INPUT_TEXT:
//                            WebElement textInputElement = findElement(driver, step.getTarget());
//                            textInputElement.sendKeys(step.getInputContent());
//                            break;
//                        default:
//                            throw new RuntimeException("Unknown step type: " + step.getType());
//                    }
//
//                    if (step.getWaitTime() != null && step.getWaitTime() > 0) {
//                        Thread.sleep(step.getWaitTime() * 1000);
//                    }
//
//                    logService.createLog(taskId, "步骤 " + currentStepIndex + " 执行完成", LocalDateTime.now());
//                }
//
//                if (!taskExecution.isStopped()) {
//                    task.setStatus(2); // 已完成
//                    task.setCurrentStep(null); // 重置当前步骤
//                    taskService.updateById(task);
//                }
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//                Thread.currentThread().interrupt();
//                logService.createLog(taskId, "任务被中断", LocalDateTime.now());
//                task.setStatus(3); // 任务被中断
//                task.setCurrentStep(null); // 重置当前步骤
//                taskService.updateById(task);
//            } catch (Exception e) {
//                e.printStackTrace();
//                logService.createLog(taskId, "执行任务时发生错误: " + e.getMessage(), LocalDateTime.now());
//                task.setStatus(3); // 任务执行失败
//                task.setCurrentStep(null); // 重置当前步骤
//                taskService.updateById(task);
//            }
//            finally {
//                taskExecutionMap.remove(taskId);
////                driver.quit();
//            }
//        });
//    }


    private WebDriver initializeWebDriver() {
        System.setProperty("webdriver.chrome.driver", "/Users/wkt/code/cursor/autoExecution/backend/src/main/resources/chromedriver");
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--remote-allow-origins=*");
        return new ChromeDriver(options);
    }

    private void updateTaskStatus(Task task, int status, Integer currentStep) {
        task.setStatus(status);
        task.setCurrentStep(currentStep);
        taskService.updateById(task);
    }

    private void logTaskEvent(int taskId, String message) {
        logService.createLog(taskId, message, LocalDateTime.now());
    }

    private void executeStep(WebDriver driver, Step step, TaskExecution taskExecution) throws InterruptedException {
        taskExecution.checkPause();
        if (taskExecution.isStopped()) {
            return;
        }

        StepType stepType = StepType.fromValue(step.getType());
        switch (stepType) {
            case CLICK:
                WebElement element = findElement(driver, step.getTarget());
                element.click();
                break;
            case INPUT:
                WebElement inputElement = findElement(driver, step.getTarget());
                inputElement.sendKeys(step.getInputContent());
                break;
            case EXECUTE_CODE:
                ((JavascriptExecutor) driver).executeScript(step.getCode());
                break;
            case OPEN_URL:
                driver.get(step.getTarget());
                break;
            case INPUT_TEXT:
                WebElement textInputElement = findElement(driver, step.getTarget());
                textInputElement.sendKeys(step.getInputContent());
                break;
            default:
                throw new RuntimeException("Unknown step type: " + step.getType());
        }

        if (step.getWaitTime() != null && step.getWaitTime() > 0) {
            Thread.sleep(step.getWaitTime() * 1000);
        }
    }

    public void executeTask(int taskId) {
        logTaskEvent(taskId, "开始执行任务");
        TaskExecution taskExecution = new TaskExecution();
        taskExecutionMap.put(taskId, taskExecution);

        executorService.submit(() -> {
            WebDriver driver = initializeWebDriver();
            Task task = null;
            try {
                task = taskService.getById(taskId);
                if (task == null) {
                    throw new RuntimeException("Task not found: " + taskId);
                }

                updateTaskStatus(task, 1, null);

                List<Step> steps = stepService.getStepsByTaskId(taskId);
                int currentStepIndex = 0;

                for (Step step : steps) {
                    currentStepIndex++;
                    updateTaskStatus(task, 1, currentStepIndex);
                    logTaskEvent(taskId, "开始执行步骤 " + currentStepIndex);

                    executeStep(driver, step, taskExecution);

                    logTaskEvent(taskId, "步骤 " + currentStepIndex + " 执行完成");
                }

                if (!taskExecution.isStopped()) {
                    updateTaskStatus(task, 2, null);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                logTaskEvent(taskId, "任务被中断");
                updateTaskStatus(task, 3, null);
            } catch (Exception e) {
                logTaskEvent(taskId, "执行任务时发生错误: " + e.getMessage());
                updateTaskStatus(task, 3, null);
            } finally {
                taskExecutionMap.remove(taskId);
//                driver.quit();
            }
        });
    }

    public void stopTask(int taskId) {
        logTaskEvent(taskId, "停止任务");
        TaskExecution taskExecution = taskExecutionMap.get(taskId);
        if (taskExecution != null) {
            taskExecution.stop();
        }
    }

    public void pauseTask(int taskId) {
        logTaskEvent(taskId, "暂停任务");
        TaskExecution taskExecution = taskExecutionMap.get(taskId);
        if (taskExecution != null) {
            taskExecution.pause();
        }
    }

    public void resumeTask(int taskId) {
        logTaskEvent(taskId, "恢复任务");
        TaskExecution taskExecution = taskExecutionMap.get(taskId);
        if (taskExecution != null) {
            taskExecution.resume();
        }
    }

    private WebElement findElement(WebDriver driver, String target) {
        Duration timeout = Duration.ofSeconds(10);
        WebDriverWait wait = new WebDriverWait(driver, timeout);

        if (target.startsWith("//")) {
            return wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(target)));
        } else {
            return wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(target)));
        }
    }
} 